﻿/*
 * %W% %E%
 *
 * Copyright (c)
 */
package com.shareinfo.base.common.file;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
 * @ClassName: FileUtil
 * @Description: TODO
 * @author Huangpeng@shareinfo.com.cn
 * @date 2013-7-17 上午10:41:32
 * 
 */
public class FileUtil {

	private static final Log logger = LogFactory.getLog(FileUtil.class);
	
	public static final int BUFFER_SIZE = 4096;

	/**
	 * 
	 * @Title: copy
	 * @Description: 拷贝输入文件内容到输出文件
	 * @param @param in
	 * @param @param out
	 * @param @throws IOException
	 * @return void
	 * @throws
	 */
	public static void copy(File in, File out) throws IOException {
		copy(new BufferedInputStream(new FileInputStream(in)),
				new BufferedOutputStream(new FileOutputStream(out)));
	}

	/**
	 * 
	 * @Title: copy
	 * @Description: 拷贝输入流到输出流，当完成后关闭流。
	 * @param @param in
	 * @param @param out
	 * @param @throws IOException
	 * @return void
	 * @throws
	 */
	public static void copy(InputStream in, OutputStream out)
			throws IOException {
		try {
			byte[] buffer = new byte[BUFFER_SIZE];
			int nrOfBytes = -1;
			while ((nrOfBytes = in.read(buffer)) != -1)
				out.write(buffer, 0, nrOfBytes);
			out.flush();
		} finally {
			try {
				in.close();
			} catch (IOException ex) {
				logger.warn("Could not close InputStream", ex);
			}
			try {
				out.close();
			} catch (IOException ex) {
				logger.warn("Could not close OutputStream", ex);
			}
		}
	}
	
	// 验证字符串是否为正确路径名的正则表达式
		private static String matches = "[A-Za-z]:\\\\[^:?\"><*]*";
		// 通过 sPath.matches(matches) 方法的返回值判断是否正确
		// sPath 为路径字符串
		private boolean flag;
		private File file;
		
	    /**
	     *  根据路径删除指定的目录或文件，无论存在与否
	     *@param sPath  要删除的目录或文件
	     *@return 删除成功返回 true，否则返回 false。
	     */
	    public boolean DeleteFolder(String sPath) {
	    	if(!sPath.matches(matches)){
	    		return false;
	    	}
	        flag = false;
	        file = new File(sPath);
	        // 判断目录或文件是否存在
	        if (!file.exists()) {  // 不存在返回 false
	            return flag;
	        } else {
	            // 判断是否为文件
	            if (file.isFile()) {  // 为文件时调用删除文件方法
	                return deleteFile(sPath);
	            } else {  // 为目录时调用删除目录方法
	                return deleteDirectory(sPath);
	            }
	        }
	    }
	    
	    /**
	     * 删除单个文件
	     * @param   sPath    被删除文件的文件名
	     * @return 单个文件删除成功返回true，否则返回false
	     */
	    public boolean deleteFile(String sPath) {
	        flag = false;
	        file = new File(sPath);
	        // 路径为文件且不为空则进行删除
	        if (file.isFile() && file.exists()) {
	            file.delete();
	            flag = true;
	        }
	        return flag;
	    }
	    
	    /**
	     * 删除目录（文件夹）以及目录下的文件
	     * @param   sPath 被删除目录的文件路径
	     * @return  目录删除成功返回true，否则返回false
	     */
	    public boolean deleteDirectory(String sPath) {
	        //如果sPath不以文件分隔符结尾，自动添加文件分隔符
	        if (!sPath.endsWith(File.separator)) {
	            sPath = sPath + File.separator;
	        }
	        File dirFile = new File(sPath);
	        //如果dir对应的文件不存在，或者不是一个目录，则退出
	        if (!dirFile.exists() || !dirFile.isDirectory()) {
	            return false;
	        }
	        flag = true;
	        //删除文件夹下的所有文件(包括子目录)
	        File[] files = dirFile.listFiles();
	        for (int i = 0; i < files.length; i++) {
	            //删除子文件
	            if (files[i].isFile()) {
	                flag = deleteFile(files[i].getAbsolutePath());
	                if (!flag) break;
	            } //删除子目录
	            else {
	                flag = deleteDirectory(files[i].getAbsolutePath());
	                if (!flag) break;
	            }
	        }
	        if (!flag) return false;
	        //删除当前目录
	        if (dirFile.delete()) {
	            return true;
	        } else {
	            return false;
	        }
	    }
}
